package com.cuit.qx.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.time.LocalDateTime;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static java.time.ZoneOffset.UTC;

public class Jwt {

    static String publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/hhfmOR+NXFAj71er6mB\n" +
            "7+rIsHtH0/X1B2BEF3LqMExvtBTagqERIIs14GdpUCvCCzslKngJijnozDWkVdcd\n" +
            "eT+VPB6CymLHuN3oW+wQy+SCKnga77MG91Dhf+WadlDELrtd19GHYoa6RoBuj2fs\n" +
            "gez41PUMwTxS2Vzka553aWyvX/z6VuV5SO97wmTvKpvjHDI6kOCYfnBpIrDXfcPF\n" +
            "k3zBfhPbeK0BkzJnTiYG/U/7eL1QbBKc3heXqf/gbjK6DroyKArM1/2vkGPLaVuR\n" +
            "F573QGwhfBA+G0m75gyWfZfO/uj8XYM46MP6nOj82qowfid79/LV75pWdLEzsSbb\n" +
            "9QIDAQAB";
    static String privateKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQD+GF+Y5H41cUCP\n" +
            "vV6vqYHv6siwe0fT9fUHYEQXcuowTG+0FNqCoREgizXgZ2lQK8ILOyUqeAmKOejM\n" +
            "NaRV1x15P5U8HoLKYse43ehb7BDL5IIqeBrvswb3UOF/5Zp2UMQuu13X0YdihrpG\n" +
            "gG6PZ+yB7PjU9QzBPFLZXORrnndpbK9f/PpW5XlI73vCZO8qm+McMjqQ4Jh+cGki\n" +
            "sNd9w8WTfMF";

    public static Claims parseJwt(String jsonWebToken) {
        if (jsonWebToken == null || !jsonWebToken.startsWith("Bearer ")) {
            throw new RuntimeException("token is not valid");
        }
        try{
            return Jwts.parser().setSigningKey(getPublicKey())
                    .parseClaimsJws(jsonWebToken.substring(7)).getBody();
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    public static String createToken () {
        Date expiration = Date.from(LocalDateTime.now(UTC).plusDays(7).toInstant(UTC));

        Map<String, Object> claims = new HashMap<>();
        claims.put("companyId", "1");
        claims.put("userId", "2");
        // 这里要注意 用到了setClaims 方法 setSubject  和 setExpiration 就不好用了
        // 可以把这两个值也放到claims里 或者不用setClaims 用 setClaim 一个一个放
        return "Bearer " + Jwts.builder()
                .setSubject("subject")
                .setExpiration(expiration)
                .setClaims(claims)
                .setIssuer("test1")
                .signWith(SignatureAlgorithm.RS256, getPrivateKey())
                .compact();
    }

    public static PublicKey getPublicKey(){
        try{
            byte[] keyBytes = Base64.getDecoder().decode(publicKey.getBytes());
            X509EncodedKeySpec keySpec=new X509EncodedKeySpec(keyBytes);
            KeyFactory keyFactory=KeyFactory.getInstance("RSA");
            return keyFactory.generatePublic(keySpec);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    public static PrivateKey getPrivateKey() {

        try {
            byte[] keyBytes;
            keyBytes = Base64.getDecoder().decode(privateKey.getBytes());
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            return keyFactory.generatePrivate(keySpec);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    public static void main(String[] args) {
        String token = createToken();
        System.out.println(token);
        Claims claims = parseJwt(token);
        System.out.println(claims.toString());
    }



}
